#ifndef GQUEUE_H_
#define GQUEUE_H_

#include <stdlib.h>
#include <string.h>

#include "utypes.h"

/** @defgroup gqueue GQueue
 * @{
 *
 * GQueue related functions.
 */

/** Generic FIFO structure definition for elements
of any type and size.
 */
typedef struct
{
	void *ptr;								///< Pointer to memory allocated for storing elements.
	int in;									///< Offset to store the next element.
	int out;								///< Offset to the next element to retrieve.
	int count;								///< Number of elements in the queue.
	int size;								///< Queue maximum size.
	int ele_size;							///< Size (in bytes) of an element of the queue.
	Bool being_accessed;					///< True if an insert/remove action is being done.
	
} GQueue;

/** Creates a new GQueue with maximum number of elements
"n_ele", each one with "ele_size" bytes.
*/
GQueue* newGQueue(int n_ele, int ele_size);

/** Puts element pointed by "ele" in the queue.
* Returns false if operation failed (the queue is full).
*/
Bool putGQueue(GQueue* q, void* ele);

/** Gets and removes the next element from queue.
*  Returns NULL if there are no elements in the queue.
*/
void* getGQueue(GQueue* q);

/** Gets (but doesn't remove) the next element from queue.
*  Returns NULL if there are no elements in the queue.
*/
void* peekGQueue(GQueue* q);

/** Removes all elements from the GQueue.
*/
void clearGQueue(GQueue* q);

/**Returns true if the queue is empty.
*/
Bool isEmptyGQueue(GQueue* q);

/** Returns true if the queue is full.
*/
Bool isFullGQueue(GQueue* q);

/** Destroys a GQueue, releasing all resources used by it.
 */
void deleteGQueue(GQueue* q);

/** @} end of gqueue */

#endif
